home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume20 / pcomm1.2 / part04 < prev    next >
Encoding:
Internet Message Format  |  1989-10-25  |  56.5 KB

  1. Subject:  v20i070:  Pcomm telecommunication package, Part04/08
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: fthood!egray
  7. Posting-number: Volume 20, Issue 70
  8. Archive-name: pcomm1.2/part04
  9.  
  10. #! /bin/sh
  11. # This is a shell archive, meaning:
  12. # 1. Remove everything above the #! /bin/sh line.
  13. # 2. Save the resulting text in a file.
  14. # 3. Execute the file with /bin/sh (not csh) to create:
  15. #    di_win.c
  16. #    dial.c
  17. #    dial_dir.h
  18. #    e_lib.c
  19. #    expand.c
  20. #    extrnl.h
  21. #    getcwd.c
  22. #    getopt.c
  23. #    help.c
  24. #    info.c
  25. #    init.c
  26. #    input.c
  27. #    list_dir.c
  28. #    ls_menu.c
  29. export PATH; PATH=/bin:/usr/bin:$PATH
  30. echo shar: "extracting 'di_win.c'" '(9205 characters)'
  31. if test -f 'di_win.c'
  32. then
  33.     echo shar: "will not over-write existing file 'di_win.c'"
  34. else
  35. sed 's/^X//' << \SHAR_EOF > 'di_win.c'
  36. X/*
  37. X * The dialing window routines.
  38. X */
  39. X
  40. X#define MAX_PASS    25
  41. X
  42. X#include <stdio.h>
  43. X#include <curses.h>
  44. X#include "config.h"
  45. X#include "dial_dir.h"
  46. X#include "misc.h"
  47. X#include "modem.h"
  48. X#include "param.h"
  49. X
  50. X/*
  51. X * The dialing window.  Its job is to kill the input routine, get a port,
  52. X * cycle thru the entries in the queue, while interpreting both the
  53. X * user's requests and the modem's responses.  A non-zero return code
  54. X * means we're ready to fire up the input routine.
  55. X */
  56. X
  57. Xint
  58. Xdial_win()
  59. X{
  60. X    extern int rc_index, fd;
  61. X    WINDOW *di_win, *newwin();
  62. X    int i, j, key, want_out, pass, tic, baud;
  63. X    long now, time();
  64. X    char *tbuf, *ctime(), *str, cr=13, *read_codes();
  65. X    void disp_queue(), dial_it(), delay_times(), input_off();
  66. X    void error_win(), line_set(), hang_up(), zap_vs(), log_calls();
  67. X    void st_line();
  68. X    unsigned int sleep();
  69. X                    /* are we already talking? */
  70. X    input_off();
  71. X    hang_up(VERBOSE);
  72. X
  73. X    touchwin(stdscr);
  74. X    refresh();
  75. X
  76. X    if (get_port())
  77. X        return(0);
  78. X    /*
  79. X     * If the phone number points to NULL, then either you're on a
  80. X     * direct line, or you want to do the dialing yourself.
  81. X     */
  82. X    if (*dir->number[dir->q_num[0]] == '\0') {
  83. X                    /* check LD permission */
  84. X        if (limit_ld(0))
  85. X            return(0);
  86. X                    /* can't talk directly to OBM */
  87. X        if (!strcmp(modem->mname[modem->m_cur], "OBM")) {
  88. X            error_win(0, "Can't access the On Board Modem directly",
  89. X             "You must use the automatic dialing feature");
  90. X            return(0);
  91. X        }
  92. X
  93. X        zap_vs();
  94. X        touchwin(stdscr);
  95. X        clear();
  96. X        printw("Connected to /dev/%s at %d baud...\n", modem->tty[modem->t_cur], dir->baud[dir->d_cur]);
  97. X        refresh();
  98. X        return(1);
  99. X    }
  100. X
  101. X    di_win = newwin(17, 70, 3, 5);
  102. X                    /* the basic window */
  103. X    mvwattrstr(di_win, 1, 20, A_BOLD, "D I A L I N G       W I N D O W");
  104. X    horizontal(di_win, 2, 0, 70);
  105. X    mvwaddstr(di_win, 4, 23, "System name:");
  106. X    mvwaddstr(di_win, 5, 23, "Pass number:");
  107. X    mvwaddstr(di_win, 6, 14, "Elapse time this try:");
  108. X    mvwaddstr(di_win, 7, 13, "Time at start of dial:");
  109. X    mvwaddstr(di_win, 8, 9, "Time at start of this try:");
  110. X    mvwaddstr(di_win, 9, 16, "Connect delay time:");
  111. X    mvwaddstr(di_win, 10, 17, "Redial delay time:");
  112. X    mvwaddstr(di_win, 11, 24, "Script/TTY:");
  113. X    mvwaddstr(di_win, 12, 16, "Result of last try:");
  114. X
  115. X    mvwaddstr(di_win, 14, 3, "<SPACE>: Recycle");
  116. X    mvwaddstr(di_win, 14, 22, "<DEL>: Remove from queue");
  117. X    mvwaddstr(di_win, 14, 49, "E: Change delays");
  118. X
  119. X                    /* the start time */
  120. X    time(&now);
  121. X    tbuf = ctime(&now);
  122. X    tbuf[19] = '\0';
  123. X    mvwaddstr(di_win, 7, 36, &tbuf[11]);
  124. X
  125. X    mvwprintw(di_win, 9, 36, "%-4d", param->c_delay);
  126. X    mvwprintw(di_win, 10, 36, "%-4d", param->r_delay);
  127. X
  128. X    box(di_win, VERT, HORZ);
  129. X    mvwaddstr(di_win, 16, 24, " Press <ESC> to abort ");
  130. X
  131. X    pass = 0;
  132. X    i = 0;
  133. X    want_out = 0;
  134. X    while (!want_out && pass <= MAX_PASS) {
  135. X        key = -1;
  136. X        pass++;
  137. X                    /* update the d_cur variable */
  138. X        dir->d_cur = dir->q_num[i];
  139. X                    /* check LD permission */
  140. X        if (limit_ld(i)) {
  141. X            want_out++;
  142. X            break;
  143. X        }
  144. X                    /* get a port */
  145. X        if (get_port()) {
  146. X            want_out++;
  147. X            break;
  148. X        }
  149. X                    /* fill in the window */
  150. X        disp_queue(di_win, dir->d_cur, pass);
  151. X
  152. X        /*
  153. X         * The actual dial routine.  The "i" is the index into the
  154. X         * queue, not the entry number.  Returns immediately without
  155. X         * waiting for a carrier.
  156. X         */
  157. X        dial_it(i);
  158. X        tty_flush(fd, 0);
  159. X
  160. X        /*
  161. X         * Here we do a time-slice between reading the result codes
  162. X         * from the modem and reading the keyboard.  The one second
  163. X         * granularity won't be too accurate, but who cares?
  164. X         */
  165. X        tic = 0;
  166. X        rc_index = 0;
  167. X        while (tic < param->c_delay) {
  168. X            if ((str = read_codes()) == NULL) {
  169. X                mvwprintw(di_win, 6, 36, "%-4d", ++tic);
  170. X                wrefresh(di_win);
  171. X            }
  172. X            else {
  173. X                /*
  174. X                 * A return code that converts to an number
  175. X                 * that is less than 300 is probably an error
  176. X                 * message.
  177. X                 */
  178. X                baud = atoi(str);
  179. X                if (baud < 300) {
  180. X                    mvwprintw(di_win, 12, 36, "%-20.20s", str);
  181. X                    wmove(di_win, 12, 36);
  182. X                    wrefresh(di_win);
  183. X                    break;
  184. X                }
  185. X                    /* we're connected */
  186. X                beep();
  187. X                clear_line(di_win, 12, 36, TRUE);
  188. X                wattrstr(di_win, A_BLINK, "CONNECTED");
  189. X                wmove(di_win, 12, 36);
  190. X                wrefresh(di_win);
  191. X                wait_key(di_win, 2);
  192. X                delwin(di_win);
  193. X
  194. X                /*
  195. X                 * Did the modem sync at a different baud
  196. X                 * rate than what we expected?
  197. X                 */
  198. X                if (dir->baud[dir->d_cur] != baud) {
  199. X                    if (can_sync(baud)) {
  200. X                        dir->baud[dir->d_cur] = baud;
  201. X                        line_set();
  202. X                    }
  203. X                }
  204. X
  205. X                zap_vs();
  206. X                touchwin(stdscr);
  207. X                clear();
  208. X                printw("Connected to %s at %d baud...\n",
  209. X                 dir->name[dir->d_cur], dir->baud[dir->d_cur]);
  210. X                refresh();
  211. X
  212. X                    /* log the call */
  213. X                log_calls(i);
  214. X                return(1);
  215. X            }
  216. X            if (tic == param->c_delay)
  217. X                break;
  218. X                    /* ok... try the keyboard */
  219. X            if ((key = wait_key(di_win, 1)) != -1)
  220. X                break;
  221. X
  222. X            mvwprintw(di_win, 6, 36, "%-4d", ++tic);
  223. X            wrefresh(di_win);
  224. X        }
  225. X        /*
  226. X         * If the modem did not return a code, then we need to
  227. X         * stop it.  Sending a CR will stop most modems cold,
  228. X         * except of course for the OBM...
  229. X         */
  230. X        if (str == NULL) {
  231. X            if (!strcmp(modem->mname[modem->m_cur], "OBM"))
  232. X                hang_up(QUIET);
  233. X            else
  234. X                write(fd, &cr, 1);
  235. X            sleep(1);
  236. X        }
  237. X                    /* if we get here, no key was pressed */
  238. X        if (key == -1) {
  239. X            clear_line(di_win, 6, 14, TRUE);
  240. X            mvwaddstr(di_win, 6, 27, "Pausing:");
  241. X                    /* no return code? */
  242. X            if (str == NULL) {
  243. X                clear_line(di_win, 12, 36, TRUE);
  244. X                waddstr(di_win, "TIMED OUT");
  245. X                wmove(di_win, 12, 36);
  246. X            }
  247. X                    /* do the pause */
  248. X            tic = 0;
  249. X            while (tic < param->r_delay) {
  250. X                if ((key = wait_key(di_win, 1)) != -1)
  251. X                    break;
  252. X                mvwprintw(di_win, 6, 36, "%-4d", ++tic);
  253. X                wrefresh(di_win);
  254. X            }
  255. X            clear_line(di_win, 6, 14, TRUE);
  256. X            waddstr(di_win, "Elapse time this try:");
  257. X        }
  258. X        mvwaddstr(di_win, 6, 36, "0   ");
  259. X                    /* Process the keystroke */
  260. X        switch (key) {
  261. X            case ' ':    /* next in the queue */
  262. X                clear_line(di_win, 12, 36, TRUE);
  263. X                waddstr(di_win, "RECYCLED");
  264. X                wmove(di_win, 12, 36);
  265. X                wrefresh(di_win);
  266. X                /* fall thru... */
  267. X            case -1:    /* no key was pressed */
  268. X                i++;
  269. X                if (i > NUM_QUEUE)
  270. X                    i = 0;
  271. X                if (dir->q_num[i] == -1)
  272. X                    i = 0;
  273. X                break;
  274. X            case DEL:    /* <DEL> key, remove from queue */
  275. X                if (dir->q_num[1] == -1) {
  276. X                    beep();
  277. X                    clear_line(di_win, 12, 36, TRUE);
  278. X                    waddstr(di_win, "NO MORE ENTRIES");
  279. X                    wmove(di_win, 12, 36);
  280. X                    wrefresh(di_win);
  281. X                    wait_key(di_win, 3);
  282. X                    break;
  283. X                }
  284. X                clear_line(di_win, 12, 36, TRUE);
  285. X                waddstr(di_win, "ENTRY DELETED");
  286. X                wmove(di_win, 12, 36);
  287. X                wrefresh(di_win);
  288. X                wait_key(di_win, 3);
  289. X
  290. X                    /* compact the queue */
  291. X                for (j=i; j<NUM_QUEUE-1; j++)
  292. X                    dir->q_num[j] = dir->q_num[j+1];
  293. X                dir->q_num[NUM_QUEUE-1] = -1;
  294. X                break;
  295. X            case 'e':
  296. X            case 'E':    /* change delay time */
  297. X                delay_times();
  298. X                touchwin(di_win);
  299. X                mvwprintw(di_win, 9, 36, "%-4d", param->c_delay);
  300. X                mvwprintw(di_win, 10, 36, "%-4d", param->r_delay);
  301. X                break;
  302. X            case ESC:    /* <ESC> key */
  303. X                beep();
  304. X                clear_line(di_win, 12, 36, TRUE);
  305. X                wattrstr(di_win, A_BLINK, "DIAL ABORTED");
  306. X                wmove(di_win, 12, 36);
  307. X                wrefresh(di_win);
  308. X                wait_key(di_win, 3);
  309. X                want_out++;
  310. X                break;
  311. X            default:
  312. X                beep();
  313. X                break;
  314. X        }
  315. X    }
  316. X                    /* clean up and go home */
  317. X    werase(di_win);
  318. X    wrefresh(di_win);
  319. X    delwin(di_win);
  320. X    if (!want_out)
  321. X        error_win(0, "Exceeded the maximum number number of dialing attempts", "");
  322. X    return(0);
  323. X}
  324. X
  325. X/*
  326. X * Display what info we know at this time.
  327. X */
  328. X
  329. Xstatic void
  330. Xdisp_queue(win, entry, pass)
  331. XWINDOW *win;
  332. Xint entry, pass;
  333. X{
  334. X    long now, time();
  335. X    char *tbuf, *ctime();
  336. X    void st_line();
  337. X                    /* redo the status line */
  338. X    st_line("");
  339. X                    /* system name */
  340. X    clear_line(win, 4, 36, TRUE);
  341. X    waddstr(win, dir->name[entry]);
  342. X                    /* pass number */
  343. X    mvwprintw(win, 5, 36, "%-4d", pass);
  344. X                    /* time of this call */
  345. X    time(&now);
  346. X    tbuf = ctime(&now);
  347. X    tbuf[19] = '\0';
  348. X    mvwaddstr(win, 8, 36, &tbuf[11]);
  349. X                    /* the script field */
  350. X    clear_line(win, 11, 36, TRUE);
  351. X    waddstr(win, dir->script[entry]);
  352. X
  353. X    wmove(win, 12, 36);
  354. X    wrefresh(win);
  355. X    return;
  356. X}
  357. X
  358. X/*
  359. X * Determine if the modem can detect the synchronization of the connected
  360. X * baud rate.  We check the modem database and see if the connect string
  361. X * is unique.  A non-zero return code means the modem can sync.
  362. X */
  363. X
  364. Xstatic int
  365. Xcan_sync(baud)
  366. Xint baud;
  367. X{
  368. X    int i;
  369. X    char *str;
  370. X                    /* feature disabled? */
  371. X    if (modem->auto_baud[modem->m_cur] != 'Y')
  372. X        return(0);
  373. X                    /* re-construct the string */
  374. X    switch (baud) {
  375. X        case 300:
  376. X            str = modem->con_3[modem->m_cur];
  377. X            break;
  378. X        case 1200:
  379. X            str = modem->con_12[modem->m_cur];
  380. X            break;
  381. X        case 2400:
  382. X            str = modem->con_24[modem->m_cur];
  383. X            break;
  384. X        case 4800:
  385. X            str = modem->con_48[modem->m_cur];
  386. X            break;
  387. X        case 9600:
  388. X            str = modem->con_96[modem->m_cur];
  389. X            break;
  390. X        case 19200:
  391. X            str = modem->con_192[modem->m_cur];
  392. X            break;
  393. X        default:
  394. X            return(0);
  395. X    }
  396. X
  397. X    if (*str == '\0')
  398. X        return(0);
  399. X                    /* test "str" against all others */
  400. X    i = 0;
  401. X    if (!strcmp(str, modem->con_3[modem->m_cur]))
  402. X        i++;
  403. X    if (!strcmp(str, modem->con_12[modem->m_cur]))
  404. X        i++;
  405. X    if (!strcmp(str, modem->con_24[modem->m_cur]))
  406. X        i++;
  407. X    if (!strcmp(str, modem->con_48[modem->m_cur]))
  408. X        i++;
  409. X    if (!strcmp(str, modem->con_96[modem->m_cur]))
  410. X        i++;
  411. X    if (!strcmp(str, modem->con_192[modem->m_cur]))
  412. X        i++;
  413. X                    /* should match only itself */
  414. X    if (i == 1)
  415. X        return(1);
  416. X    return(0);
  417. X}
  418. SHAR_EOF
  419. if test 9205 -ne "`wc -c < 'di_win.c'`"
  420. then
  421.     echo shar: "error transmitting 'di_win.c'" '(should have been 9205 characters)'
  422. fi
  423. fi
  424. echo shar: "extracting 'dial.c'" '(7970 characters)'
  425. if test -f 'dial.c'
  426. then
  427.     echo shar: "will not over-write existing file 'dial.c'"
  428. else
  429. sed 's/^X//' << \SHAR_EOF > 'dial.c'
  430. X/*
  431. X * The routines that dial the modem and listen for the return codes.
  432. X */
  433. X
  434. X#define HZ    60
  435. X
  436. X#include <stdio.h>
  437. X#include <sys/types.h>
  438. X#include <sys/times.h>
  439. X#include "config.h"
  440. X#include "dial_dir.h"
  441. X#include "misc.h"
  442. X#include "modem.h"
  443. X#include "param.h"
  444. X
  445. X#ifdef UNIXPC
  446. X#include <sys/phone.h>
  447. X#endif /* UNIXPC */
  448. X
  449. X/*
  450. X * Get the dial string ready, send it to the modem.  The parameter is not
  451. X * the actual entry number, it is an index into the queue.
  452. X */
  453. X
  454. Xvoid
  455. Xdial_it(num)
  456. Xint num;
  457. X{
  458. X    extern int fd;
  459. X    int i, skip;
  460. X    char s[100], number[40], *strcpy(), *strcat(), *n, *strchr();
  461. X    void send_str();
  462. X#ifdef UNIXPC
  463. X    struct updata pbuf;
  464. X    unsigned int sleep();
  465. X#endif /* UNIXPC */
  466. X
  467. X    /*
  468. X     * Create the string to be sent to the modem.  The long distance
  469. X     * codes are added if they are requested.
  470. X     */
  471. X    s[0] = '\0';
  472. X    strcpy(s, modem->dial[modem->m_cur]);
  473. X
  474. X    switch (dir->q_ld[num]) {
  475. X        case 0:            /* no ld code requested */
  476. X            break;
  477. X        case '+':
  478. X            strcat(s, param->ld_plus);
  479. X            break;
  480. X        case '-':
  481. X            strcat(s, param->ld_minus);
  482. X            break;
  483. X        case '@':
  484. X            strcat(s, param->ld_at);
  485. X            break;
  486. X        case '#':
  487. X            strcat(s, param->ld_pound);
  488. X            break;
  489. X    }
  490. X    /*
  491. X     * Purify the phone number by removing all the pretty characters
  492. X     * that don't need to be sent to the modem.  Typically the "-",
  493. X     * "(", ")", and space characters are just for looks.  To prevent
  494. X     * this action, prepend a "\" to the character.
  495. X     */
  496. X    i = 0;
  497. X    skip = 0;
  498. X    n = dir->number[dir->q_num[num]];
  499. X    while (*n) {
  500. X        if (*n == '\\' && !skip) {
  501. X            skip++;
  502. X            n++;
  503. X            continue;
  504. X        }
  505. X        if (!strchr("-() ", *n) || skip)
  506. X            number[i++] = *n;
  507. X        n++;
  508. X        skip = 0;
  509. X    }
  510. X    number[i] = '\0';
  511. X                    /* add it to the string */
  512. X    strcat(s, number);
  513. X    strcat(s, modem->suffix[modem->m_cur]);
  514. X#ifdef DEBUG
  515. X    fprintf(stderr, "raw dial string: \"%s\"\n", s);
  516. X#endif /* DEBUG */
  517. X
  518. X#ifdef UNIXPC
  519. X                    /* special case for OBM */
  520. X    if (!strcmp(modem->mname[modem->m_cur], "OBM")) {
  521. X                    /* prepare the modem */
  522. X        pbuf.c_lineparam = DATA|DTMF;
  523. X        pbuf.c_waitdialtone = 5;
  524. X        pbuf.c_linestatus = 0;
  525. X        pbuf.c_feedback = SPEAKERON|NORMSPK;
  526. X        pbuf.c_waitflash = 500;
  527. X        ioctl(fd, PIOCSETP, &pbuf);
  528. X        sleep(1);
  529. X                    /* connect the dialer */
  530. X        ioctl(fd, PIOCRECONN);
  531. X        sleep(1);
  532. X                    /* dial each digit */
  533. X        n = s;
  534. X        while (*n) {
  535. X                    /* switch tone/pulse dialing? */
  536. X            switch (*n) {
  537. X                case '^':
  538. X                    pbuf.c_lineparam = DATA|PULSE;
  539. X                    ioctl(fd, PIOCSETP, &pbuf);
  540. X                    break;
  541. X                case '%':
  542. X                    pbuf.c_lineparam = DATA|DTMF;
  543. X                    ioctl(fd, PIOCSETP, &pbuf);
  544. X                    break;
  545. X                default:
  546. X                    ioctl(fd, PIOCDIAL, n);
  547. X                    break;
  548. X            }
  549. X            n++;
  550. X        }
  551. X        return;
  552. X    }
  553. X#endif /* UNIXPC */
  554. X
  555. X    send_str(s, SLOW);
  556. X    return;
  557. X}
  558. X
  559. X/*
  560. X * Send a string to the modem.  Performs all the character synonym
  561. X * translations.
  562. X */
  563. X
  564. Xvoid
  565. Xsend_str(s, slow)
  566. Xchar *s;
  567. Xint slow;
  568. X{
  569. X    extern int fd;
  570. X    int skip, has_pause;
  571. X    char *strchr();
  572. X    unsigned int sleep();
  573. X    void do_pause();
  574. X                    /* empty string? */
  575. X    if (s == NULL || *s == '\0')
  576. X        return;
  577. X
  578. X                    /* contains a pause? */
  579. X    has_pause = 0;
  580. X    if (strchr(s, '~'))
  581. X        has_pause++;
  582. X
  583. X    tty_flush(fd, 1);
  584. X    /*
  585. X     * Change the character synonyms to their real values.  Writes
  586. X     * the characters to the modem.  To remove the special meaning
  587. X     * of one of the characters, prepend a "\" to it.
  588. X     */
  589. X    skip = 0;
  590. X    while (*s) {
  591. X                    /* send the literal character */
  592. X        if (skip) {
  593. X            skip = 0;
  594. X            write(fd, s, 1);
  595. X            if (has_pause || slow)
  596. X                tty_drain(fd);
  597. X            if (slow)
  598. X                do_pause();
  599. X#ifdef DEBUG
  600. X            fprintf(stderr, "send_str: \"%c\", %02x, %03o, %d\n", *s, *s, *s, *s);
  601. X#endif /* DEBUG */
  602. X            s++;
  603. X            continue;
  604. X        }
  605. X                    /* turn off the special meaning */
  606. X        if (*s == '\\') {
  607. X            skip++;
  608. X            s++;
  609. X            continue;
  610. X        }
  611. X                    /* pause synonym */
  612. X        if (*s == param->pause_char) {
  613. X            sleep(1);
  614. X            s++;
  615. X            continue;
  616. X        }
  617. X                    /* carriage return synonym */
  618. X        if (*s == param->cr_char)
  619. X            *s = '\r';
  620. X                    /* 2 character control sequence */
  621. X        if (*s == param->ctrl_char) {
  622. X            s++;
  623. X                    /* premature EOF? */
  624. X            if (*s == '\0')
  625. X                break;
  626. X                    /* upper and lower case */
  627. X            if (*s > '_')
  628. X                *s -= 96;
  629. X            else
  630. X                *s -= 64;
  631. X        }
  632. X                    /* escape synonym */
  633. X        if (*s == param->esc_char)
  634. X            *s = ESC;
  635. X                    /* modem break synonym */
  636. X        if (*s == param->brk_char) {
  637. X            tty_break(fd);
  638. X            sleep(1);
  639. X            s++;
  640. X            continue;
  641. X        }
  642. X
  643. X        write(fd, s, 1);
  644. X#ifdef DEBUG
  645. X        fprintf(stderr, "send_str: \"%c\", %02x, %03o, %d\n", *s, *s, *s, *s);
  646. X#endif /* DEBUG */
  647. X        /*
  648. X         * Because the pause char makes the timing critical, we
  649. X         * wait until the buffer is clear before we continue.
  650. X         */
  651. X        if (has_pause || slow)
  652. X            tty_drain(fd);
  653. X        if (slow)
  654. X            do_pause();
  655. X        s++;
  656. X    }
  657. X    return;
  658. X}
  659. X
  660. X/*
  661. X * Read the result codes coming back from the modem.  Test for the 6
  662. X * "connect" strings and the 4 "no connect" strings.  Return the connected
  663. X * baud rate (as a string) or the error message.
  664. X */
  665. X
  666. Xchar rc_buf[512];
  667. Xint rc_index;
  668. X
  669. Xchar *
  670. Xread_codes()
  671. X{
  672. X    extern int fd;
  673. X    int i;
  674. X    char c;
  675. X#ifdef UNIXPC
  676. X    unsigned int sleep();
  677. X    struct updata pbuf;
  678. X                    /* special case for OBM */
  679. X    if (!strcmp(modem->mname[modem->m_cur], "OBM")) {
  680. X        ioctl(fd, PIOCGETP, &pbuf);
  681. X
  682. X        /*
  683. X         * The OBM doesn't use a return message to announce the
  684. X         * connection to a remote, so we fake one.  The 1200
  685. X         * is quite arbitrary... it is not an indicator of the
  686. X         * connected baud rate.
  687. X         */
  688. X        if (pbuf.c_linestatus & MODEMCONNECTED)
  689. X            return("1200");
  690. X
  691. X        sleep(1);
  692. X        return(NULL);
  693. X    }
  694. X#endif /* UNIXPC */
  695. X                    /* search for key words */
  696. X    for (; rc_index<511; rc_index++) {
  697. X        if ((i = getc_line(1)) <= 0)
  698. X            return(NULL);
  699. X
  700. X        c = i & 0x7f;
  701. X#ifdef DEBUG
  702. X        fprintf(stderr, "read_codes: \"%c\", %02x, %03o, %d\n", c, c, c, c);
  703. X#endif /* DEBUG */
  704. X                    /* no NULLs please */
  705. X        if (c == '\0') {
  706. X            if (rc_index)
  707. X                rc_index--;
  708. X            continue;
  709. X        }
  710. X        rc_buf[rc_index] = c;
  711. X        rc_buf[rc_index+1] = '\0';
  712. X                    /* the connect strings */
  713. X        if (match(rc_buf, modem->con_3[modem->m_cur]))
  714. X            return("300");
  715. X
  716. X        if (match(rc_buf, modem->con_12[modem->m_cur]))
  717. X            return("1200");
  718. X
  719. X        if (match(rc_buf, modem->con_24[modem->m_cur]))
  720. X            return("2400");
  721. X
  722. X        if (match(rc_buf, modem->con_48[modem->m_cur]))
  723. X            return("4800");
  724. X
  725. X        if (match(rc_buf, modem->con_96[modem->m_cur]))
  726. X            return("9600");
  727. X
  728. X        if (match(rc_buf, modem->con_192[modem->m_cur]))
  729. X            return("19200");
  730. X
  731. X                    /* the no connect strings */
  732. X        if (match(rc_buf, modem->no_con1[modem->m_cur]))
  733. X            return(modem->no_con1[modem->m_cur]);
  734. X
  735. X        if (match(rc_buf, modem->no_con2[modem->m_cur]))
  736. X            return(modem->no_con2[modem->m_cur]);
  737. X
  738. X        if (match(rc_buf, modem->no_con3[modem->m_cur]))
  739. X            return(modem->no_con3[modem->m_cur]);
  740. X
  741. X        if (match(rc_buf, modem->no_con4[modem->m_cur]))
  742. X            return(modem->no_con4[modem->m_cur]);
  743. X    }
  744. X                    /* ran out of buffer? */
  745. X    return("ERROR");
  746. X}
  747. X
  748. X/*
  749. X * Test for a match between two character strings.  A non-zero return code
  750. X * means that s2 was found at the end of s1.
  751. X */
  752. X
  753. Xstatic int
  754. Xmatch(s1, s2)
  755. Xchar *s1, *s2;
  756. X{
  757. X    register int i;
  758. X    int skip, diff;
  759. X    char new[40];
  760. X                    /* if no string to match */
  761. X    if (*s2 == '\0')
  762. X        return(0);
  763. X                    /* translate synonyms */
  764. X    i = 0;
  765. X    skip = 0;
  766. X    while (*s2) {
  767. X                    /* literal character */
  768. X        if (skip) {
  769. X            skip = 0;
  770. X            new[i++] = *s2;
  771. X            s2++;
  772. X            continue;
  773. X        }
  774. X                    /* turn off the special meaning */
  775. X        if (*s2 == '\\') {
  776. X            skip++;
  777. X            s2++;
  778. X            continue;
  779. X        }
  780. X                    /* carriage return synonym */
  781. X        if (*s2 == param->cr_char)
  782. X            *s2 = '\r';
  783. X
  784. X                    /* 2 character control sequence */
  785. X        if (*s2 == param->ctrl_char) {
  786. X            s2++;
  787. X            if (*s2 == '\0')
  788. X                break;
  789. X            if (*s2 > '_')
  790. X                *s2 -= 96;
  791. X            else
  792. X                *s2 -= 64;
  793. X        }
  794. X                    /* escape synonym */
  795. X        if (*s2 == param->esc_char)
  796. X            *s2 = ESC;
  797. X
  798. X        new[i++] = *s2;
  799. X        s2++;
  800. X    }
  801. X    new[i] = '\0';
  802. X
  803. X    diff = strlen(s1) - strlen(new);
  804. X                    /* is it possible? */
  805. X    if (diff < 0)
  806. X        return(0);
  807. X                    /* test it out */
  808. X    if (!strcmp(&s1[diff], new))
  809. X        return(1);
  810. X    return(0);
  811. X}
  812. X
  813. X/*
  814. X * Apparently some modems can't take input at the rated speed while
  815. X * in the command mode.  Therefore, a 0.10 sec pause a required between
  816. X * characters.
  817. X */
  818. X
  819. Xvoid
  820. Xdo_pause()
  821. X{
  822. X    struct tms t;
  823. X    long t1;
  824. X
  825. X    t1 = times(&t);
  826. X    while ((times(&t) - t1) < HZ/10)
  827. X        ;
  828. X    return;
  829. X}
  830. SHAR_EOF
  831. if test 7970 -ne "`wc -c < 'dial.c'`"
  832. then
  833.     echo shar: "error transmitting 'dial.c'" '(should have been 7970 characters)'
  834. fi
  835. fi
  836. echo shar: "extracting 'dial_dir.h'" '(932 characters)'
  837. if test -f 'dial_dir.h'
  838. then
  839.     echo shar: "will not over-write existing file 'dial_dir.h'"
  840. else
  841. sed 's/^X//' << \SHAR_EOF > 'dial_dir.h'
  842. X/*
  843. X * The dialing directory structure.  The first eight elements are
  844. X * contained in the pcomm.dial_dir file.
  845. X */
  846. X
  847. X#define NUM_DIR        100
  848. X#define NUM_QUEUE    10
  849. X#define FAST        0
  850. X#define SLOW        1
  851. X#define QUIET        0
  852. X#define VERBOSE        1
  853. X
  854. Xstruct DIAL_DIR {
  855. X    char    *name[NUM_DIR+1];    /* name of system being called */
  856. X    char    *number[NUM_DIR+1];    /* phone number */
  857. X    int    baud[NUM_DIR+1];    /* baud rate */
  858. X    char    parity[NUM_DIR+1];    /* parity */
  859. X    int    dbits[NUM_DIR+1];    /* data bits */
  860. X    int    sbits[NUM_DIR+1];    /* stop bits */
  861. X    char    duplex[NUM_DIR+1];    /* duplex (F = full, H = half) */
  862. X    char    *script[NUM_DIR+1];    /* script name (or TTY) */
  863. X
  864. X    int    q_num[NUM_QUEUE];    /* entry numbers in the queue */
  865. X    char    q_ld[NUM_QUEUE];    /* LD codes in the queue */
  866. X
  867. X    int    d_entries;        /* number of entries in the file */
  868. X    int    d_cur;            /* the current entry */
  869. X
  870. X    char    *d_path;        /* path to the pcomm.dial_dir file */
  871. X};
  872. X
  873. X#ifndef MAIN
  874. Xextern struct DIAL_DIR *dir;
  875. X#endif /* MAIN */
  876. SHAR_EOF
  877. if test 932 -ne "`wc -c < 'dial_dir.h'`"
  878. then
  879.     echo shar: "error transmitting 'dial_dir.h'" '(should have been 932 characters)'
  880. fi
  881. fi
  882. echo shar: "extracting 'e_lib.c'" '(3624 characters)'
  883. if test -f 'e_lib.c'
  884. then
  885.     echo shar: "will not over-write existing file 'e_lib.c'"
  886. else
  887. sed 's/^X//' << \SHAR_EOF > 'e_lib.c'
  888. X/*
  889. X * Routines to manipulate the pcomm.extrnl file
  890. X */
  891. X
  892. X#include <stdio.h>
  893. X#include "extrnl.h"
  894. X
  895. X/*
  896. X * Read the external file transfer program database.  Returns a pointer
  897. X * to a static area containing the EXTRNL structure.  This support file is 
  898. X * optional.
  899. X */
  900. X
  901. Xstruct EXTRNL *
  902. Xread_extrnl(extra)
  903. Xchar *extra;
  904. X{
  905. X    extern char *null_ptr;
  906. X    FILE *fp, *my_fopen();
  907. X    int i, line, up, entry, oops;
  908. X    char *str_dup(), buf[200], message[80], token[40], *str_tok(), *str;
  909. X    char *sep, *temp_token, *findfile();
  910. X    static struct EXTRNL e;
  911. X    void error_win();
  912. X
  913. X    if ((e.e_path = findfile(extra, "pcomm.extrnl")) == NULL) {
  914. X                    /* not required to exist */
  915. X        for (i=0; i<3; i++) {
  916. X            e.name[0][i] = null_ptr;
  917. X            e.command[0][i] = null_ptr;
  918. X            e.prompt[0][i] = 'N';
  919. X            e.name[1][i] = null_ptr;
  920. X            e.command[1][i] = null_ptr;
  921. X            e.prompt[1][i] = 'N';
  922. X        }
  923. X        e.up_entries = 0;
  924. X        e.dn_entries = 0;
  925. X
  926. X        return(&e);
  927. X    }
  928. X
  929. X    if (!(fp = my_fopen(e.e_path, "r"))) {
  930. X        sprintf(buf, "\"%s\" for read", e.e_path);
  931. X        error_win(1, "Can't open external program file", buf);
  932. X    }
  933. X
  934. X    sep = ";;\n";
  935. X    line = 0;
  936. X    up = 1;
  937. X    oops = 0;
  938. X    while (fgets(buf, 200, fp) != NULL) {
  939. X        line++;
  940. X        if (line <= 3)
  941. X            entry = line-1;
  942. X        else {
  943. X            up = 0;
  944. X            entry = line-4;
  945. X        }
  946. X                    /* get the token */
  947. X        if (!(temp_token = str_tok(buf, '='))) {
  948. X            sprintf(message, "is missing a token at line %d", line);
  949. X            oops++;
  950. X            break;
  951. X        }
  952. X        /*
  953. X         * Parse the rest of the line.  This is similar to using
  954. X         * the "real" strtok() function, but this version returns
  955. X         * a pointer to NULL if the token is missing.  Note the
  956. X         * use of the array of separators.
  957. X         */
  958. X        for (i=0; i<3; i++) {
  959. X            if (!(str = str_tok((char *) NULL, sep[i]))) {
  960. X                sprintf(message, "is missing a parameter at line %d", line);
  961. X                oops++;
  962. X                break;
  963. X            }
  964. X            switch(i) {
  965. X                case 0:
  966. X                    e.name[up][entry] = str_dup(str);
  967. X                    break;
  968. X                case 1:
  969. X                    e.command[up][entry] = str_dup(str);
  970. X                    break;
  971. X                case 2:
  972. X                    e.prompt[up][entry] = *str;
  973. X                    break;
  974. X            }
  975. X        }
  976. X        if (oops)
  977. X            break;
  978. X
  979. X                    /* sanity checking */
  980. X        if (up)
  981. X            sprintf(token, "SEND_%d", entry+1);
  982. X        else
  983. X            sprintf(token, "RCV_%d", entry+1);
  984. X
  985. X        if (strcmp(temp_token, token)) {
  986. X            sprintf(message, "is corrupted at line %d", line);
  987. X            oops++;
  988. X            break;
  989. X        }
  990. X    }
  991. X    fclose(fp);
  992. X
  993. X    if (oops) {
  994. X        sprintf(buf, "External program file \"%s\"", e.e_path);
  995. X        error_win(1, buf, message);
  996. X    }
  997. X                    /* find number of upload entries */
  998. X    for (i=0; i<3; i++) {
  999. X        if (e.name[1][i] == null_ptr)
  1000. X            break;
  1001. X    }
  1002. X    e.up_entries = i;
  1003. X                    /* find number of download entries */
  1004. X    for (i=0; i<3; i++) {
  1005. X        if (e.name[0][i] == null_ptr)
  1006. X            break;
  1007. X    }
  1008. X    e.dn_entries = i;
  1009. X                    /* if empty database */
  1010. X    if (!e.up_entries || !e.dn_entries) {
  1011. X        sprintf(buf, "External program file \"%s\"", e.e_path);
  1012. X        error_win(0, buf, "has no data");
  1013. X    }
  1014. X
  1015. X    return(&e);
  1016. X}
  1017. X
  1018. X/*
  1019. X * Update the external file transfer program database.  A non-zero return
  1020. X * code means a non-fatal error.
  1021. X */
  1022. X
  1023. Xint
  1024. Xup_extrnl()
  1025. X{
  1026. X    FILE *fp, *my_fopen();
  1027. X    int i, up, entry;
  1028. X    char buf[200];
  1029. X    void error_win();
  1030. X                    /* open for write */
  1031. X    if (!(fp = my_fopen(extrnl->e_path, "w"))) {
  1032. X        sprintf(buf, "\"%s\"", extrnl->e_path);
  1033. X        error_win(0, "No write permission on externl program file", buf);
  1034. X        return(1);
  1035. X    }
  1036. X                    /* put 'em back */
  1037. X    up = 1;
  1038. X    for (i=0; i<6; i++) {
  1039. X        if (i < 3)
  1040. X            entry = i;
  1041. X        else {
  1042. X            up = 0;
  1043. X            entry = i-3;
  1044. X        }
  1045. X        if (up)
  1046. X            fprintf(fp, "SEND_%d=%s;%s;%c\n", entry+1, extrnl->name[up][entry], extrnl->command[up][entry], extrnl->prompt[up][entry]);
  1047. X        else
  1048. X            fprintf(fp, "RCV_%d=%s;%s;%c\n", entry+1, extrnl->name[up][entry], extrnl->command[up][entry], extrnl->prompt[up][entry]);
  1049. X    }
  1050. X
  1051. X    fclose(fp);
  1052. X    return(0);
  1053. X}
  1054. SHAR_EOF
  1055. if test 3624 -ne "`wc -c < 'e_lib.c'`"
  1056. then
  1057.     echo shar: "error transmitting 'e_lib.c'" '(should have been 3624 characters)'
  1058. fi
  1059. fi
  1060. echo shar: "extracting 'expand.c'" '(2873 characters)'
  1061. if test -f 'expand.c'
  1062. then
  1063.     echo shar: "will not over-write existing file 'expand.c'"
  1064. else
  1065. sed 's/^X//' << \SHAR_EOF > 'expand.c'
  1066. X/*
  1067. X * Do file name expansion with "native" shell.  Using the native shell
  1068. X * (as described in the SHELL environmental variable) allows for csh or
  1069. X * ksh abbreviations that sh doesn't recognize.  Returns a pointer to
  1070. X * a static area.
  1071. X */
  1072. X
  1073. X#define EXPAND_BUF    2048
  1074. X
  1075. X#include <stdio.h>
  1076. X#include <signal.h>
  1077. X#include <fcntl.h>
  1078. X#include "config.h"
  1079. X
  1080. Xchar *
  1081. Xexpand(input)
  1082. Xchar *input;
  1083. X{
  1084. X    extern char *null_ptr;
  1085. X    FILE *pfp, *n_popen();
  1086. X    int last;
  1087. X    char buf[1024], *strpbrk(), *strcpy();
  1088. X    static char ans[EXPAND_BUF];
  1089. X
  1090. X                    /* same rules as str_dup() */
  1091. X    if (input == NULL)
  1092. X        return(NULL);
  1093. X    if (*input == '\0')
  1094. X        return(null_ptr);
  1095. X                    /* any thing to expand? */
  1096. X    if (!strpbrk(input, "$*{}[]\\?~")) {
  1097. X        strcpy(ans, input);
  1098. X        return(ans);
  1099. X    }
  1100. X                    /* popen an echo */
  1101. X    sprintf(buf, "echo %s", input);
  1102. X
  1103. X    pfp = n_popen(buf, "r");
  1104. X    fgets(ans, EXPAND_BUF, pfp);
  1105. X    n_pclose(pfp);
  1106. X
  1107. X    if (!strlen(ans)) {
  1108. X        strcpy(ans, input);
  1109. X        return(ans);
  1110. X    }
  1111. X    /*
  1112. X     * A horrible kludge...  if the last character is not a line
  1113. X     * feed, then the csh has returned an error message.  Otherwise
  1114. X     * zap the line feed.
  1115. X     */
  1116. X    last = strlen(ans) -1;
  1117. X    if (ans[last] != '\n') {
  1118. X        strcpy(ans, input);
  1119. X        return(ans);
  1120. X    }
  1121. X    else
  1122. X        ans[last] = '\0';
  1123. X
  1124. X    return(ans);
  1125. X}
  1126. X
  1127. X#define    tst(a,b) (*mode == 'r'? (b) : (a))
  1128. X#define    RDR    0
  1129. X#define    WTR    1
  1130. Xstatic int popen_pid[20];
  1131. X
  1132. XFILE *
  1133. Xn_popen(cmd, mode)
  1134. Xchar *cmd, *mode;
  1135. X{
  1136. X    int myside, hisside, ppid, p[2];
  1137. X    char *shellpath, *shell, *flags, *getenv(), *strrchr();
  1138. X    void _exit();
  1139. X
  1140. X    if (pipe(p) < 0)
  1141. X        return NULL;
  1142. X
  1143. X    myside = tst(p[WTR], p[RDR]);
  1144. X    hisside = tst(p[RDR], p[WTR]);
  1145. X                    /* get the environmental variable */
  1146. X    shellpath = getenv("SHELL");
  1147. X    if (shellpath == NULL || *shellpath == '\0')
  1148. X        shellpath = "/bin/sh";
  1149. X
  1150. X    if (shell = strrchr(shellpath, '/'))
  1151. X        shell++;
  1152. X    else {
  1153. X        shellpath = "/bin/sh";
  1154. X        shell = "sh";
  1155. X    }
  1156. X                    /* fix up the flags */
  1157. X    if (!strcmp(shell, "csh"))
  1158. X        flags = "-fc";
  1159. X    else
  1160. X        flags = "-c";        /* Korn shell too */
  1161. X
  1162. X    if (!(ppid = fork())) {
  1163. X        int stdio;
  1164. X                    /* no error messages please */
  1165. X        close(2);
  1166. X        open("/dev/null", O_WRONLY);
  1167. X#ifdef SETUGID
  1168. X        setgid(getgid());
  1169. X        setuid(getuid());
  1170. X#endif /* SETUGID */
  1171. X        stdio = tst(0, 1);
  1172. X        close(myside);
  1173. X        close(stdio);
  1174. X        fcntl(hisside, F_DUPFD, stdio);
  1175. X        close(hisside);
  1176. X        execl(shellpath, shell, flags, cmd, (char *) 0);
  1177. X        _exit(1);
  1178. X    }
  1179. X    if (ppid == -1) {
  1180. X        close(myside);
  1181. X        close(hisside);
  1182. X        return NULL;
  1183. X    }
  1184. X
  1185. X    popen_pid[myside] = ppid;
  1186. X
  1187. X    close(hisside);
  1188. X    return(fdopen(myside, mode));
  1189. X}
  1190. X
  1191. Xn_pclose(ptr)
  1192. XFILE *ptr;
  1193. X{
  1194. X    SIG_TYPE (*hstat)(), (*istat)(), (*qstat)();
  1195. X    int f, r, sig_status;
  1196. X
  1197. X    f = fileno(ptr);
  1198. X    fclose(ptr);
  1199. X    istat = signal(SIGINT, SIG_IGN);
  1200. X    qstat = signal(SIGQUIT, SIG_IGN);
  1201. X    hstat = signal(SIGHUP, SIG_IGN);
  1202. X
  1203. X    while ((r = wait(&sig_status)) != popen_pid[f] && r != -1)
  1204. X        ;
  1205. X
  1206. X    if (r == -1)
  1207. X        sig_status = -1;
  1208. X
  1209. X    signal(SIGINT, istat);
  1210. X    signal(SIGQUIT, qstat);
  1211. X    signal(SIGHUP, hstat);
  1212. X    return(sig_status);
  1213. X}
  1214. SHAR_EOF
  1215. if test 2873 -ne "`wc -c < 'expand.c'`"
  1216. then
  1217.     echo shar: "error transmitting 'expand.c'" '(should have been 2873 characters)'
  1218. fi
  1219. fi
  1220. echo shar: "extracting 'extrnl.h'" '(623 characters)'
  1221. if test -f 'extrnl.h'
  1222. then
  1223.     echo shar: "will not over-write existing file 'extrnl.h'"
  1224. else
  1225. sed 's/^X//' << \SHAR_EOF > 'extrnl.h'
  1226. X/*
  1227. X * The external file transfer program database.  The list is limited to
  1228. X * 3 uploads and 3 downloads because the xfer_menu() routine uses single
  1229. X * character input (and these selections become 7, 8, and 9).
  1230. X */
  1231. X
  1232. Xstruct EXTRNL {
  1233. X    char    *name[2][3];        /* program name (for display only) */
  1234. X    char    *command[2][3];        /* the command line */
  1235. X    char    prompt[2][3];        /* need to prompt for names? */
  1236. X
  1237. X    int    up_entries;        /* number of up entries in the file */
  1238. X    int    dn_entries;        /* number of down entries in the file */
  1239. X
  1240. X    char    *e_path;        /* path to the pcomm.extrnl file */
  1241. X};
  1242. X
  1243. X#ifndef MAIN
  1244. Xextern struct EXTRNL *extrnl;
  1245. X#endif /* MAIN */
  1246. SHAR_EOF
  1247. if test 623 -ne "`wc -c < 'extrnl.h'`"
  1248. then
  1249.     echo shar: "error transmitting 'extrnl.h'" '(should have been 623 characters)'
  1250. fi
  1251. fi
  1252. echo shar: "extracting 'getcwd.c'" '(387 characters)'
  1253. if test -f 'getcwd.c'
  1254. then
  1255.     echo shar: "will not over-write existing file 'getcwd.c'"
  1256. else
  1257. sed 's/^X//' << \SHAR_EOF > 'getcwd.c'
  1258. X/*
  1259. X * Can you believe it???  Masscomps don't have a function to return the
  1260. X * current working directory while in the AT&T universe!
  1261. X */
  1262. X
  1263. X#include <stdio.h>
  1264. X
  1265. Xchar *
  1266. Xgetcwd(buf, size)
  1267. Xchar *buf;
  1268. Xint size;
  1269. X{
  1270. X    FILE *pfp, *popen();
  1271. X
  1272. X    if (!(pfp = popen("pwd", "r")))
  1273. X        return(".");
  1274. X
  1275. X    fgets(buf, size, pfp);
  1276. X    pclose(pfp);
  1277. X                    /* zap the new line */
  1278. X    buf[strlen(buf)-1] = '\0';
  1279. X    return(buf);
  1280. X}
  1281. SHAR_EOF
  1282. if test 387 -ne "`wc -c < 'getcwd.c'`"
  1283. then
  1284.     echo shar: "error transmitting 'getcwd.c'" '(should have been 387 characters)'
  1285. fi
  1286. fi
  1287. echo shar: "extracting 'getopt.c'" '(1035 characters)'
  1288. if test -f 'getopt.c'
  1289. then
  1290.     echo shar: "will not over-write existing file 'getopt.c'"
  1291. else
  1292. sed 's/^X//' << \SHAR_EOF > 'getopt.c'
  1293. X/*
  1294. X * Parse the command line and return option flags and arguments
  1295. X */
  1296. X
  1297. X#include <stdio.h>
  1298. X
  1299. Xint optind = 1;
  1300. Xchar *optarg;
  1301. X
  1302. Xint
  1303. Xgetopt(argc, argv, opts)
  1304. Xint argc;
  1305. Xchar *argv[];
  1306. Xchar *opts;
  1307. X{
  1308. X    static int sp = 1;
  1309. X    int c, strcmp();
  1310. X    char *cp, *strchr();
  1311. X
  1312. X    if (sp == 1) {
  1313. X        if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
  1314. X            return(EOF);
  1315. X        else if (strcmp(argv[optind], "--") == 0) {
  1316. X            optind++;
  1317. X            return(EOF);
  1318. X        }
  1319. X    }
  1320. X    c = argv[optind][sp];
  1321. X    if (c == ':' || (cp=strchr(opts, c)) == NULL) {
  1322. X        fprintf(stderr, "%s: illegal option \"%c\"\n", argv[0], c);
  1323. X        if (argv[optind][++sp] == '\0') {
  1324. X            optind++;
  1325. X            sp = 1;
  1326. X        }
  1327. X        return('?');
  1328. X    }
  1329. X    if (*++cp == ':') {
  1330. X        if (argv[optind][sp+1] != '\0')
  1331. X            optarg = &argv[optind++][sp+1];
  1332. X        else if (++optind >= argc) {
  1333. X            fprintf(stderr, "%s: option \"%c\" requires an argument\n", argv[0], c);
  1334. X            sp = 1;
  1335. X            return('?');
  1336. X        } else
  1337. X            optarg = argv[optind++];
  1338. X        sp = 1;
  1339. X    } else {
  1340. X        if (argv[optind][++sp] == '\0') {
  1341. X            sp = 1;
  1342. X            optind++;
  1343. X        }
  1344. X        optarg = NULL;
  1345. X    }
  1346. X    return(c);
  1347. X}
  1348. SHAR_EOF
  1349. if test 1035 -ne "`wc -c < 'getopt.c'`"
  1350. then
  1351.     echo shar: "error transmitting 'getopt.c'" '(should have been 1035 characters)'
  1352. fi
  1353. fi
  1354. echo shar: "extracting 'help.c'" '(1779 characters)'
  1355. if test -f 'help.c'
  1356. then
  1357.     echo shar: "will not over-write existing file 'help.c'"
  1358. else
  1359. sed 's/^X//' << \SHAR_EOF > 'help.c'
  1360. X/*
  1361. X * Display the help screen.  Press any key to continue.  If the ascii_hot
  1362. X * string is more than 4 characters wide, this screen will look silly.
  1363. X * Maybe one day, this will also contain full page descriptions of each
  1364. X * command.
  1365. X */
  1366. X
  1367. X#include <stdio.h>
  1368. X#include <curses.h>
  1369. X#include "config.h"
  1370. X#include "misc.h"
  1371. X
  1372. Xvoid
  1373. Xhelp_screen(hot)
  1374. Xchar *hot;
  1375. X{
  1376. X    extern int fd;
  1377. X    WINDOW *h_win, *newwin();
  1378. X
  1379. X    h_win = newwin(17, 80, 0, 0);
  1380. X
  1381. X    mvwattrstr(h_win, 1, 29, A_BOLD, "P C O M M       H E L P\n");
  1382. X    horizontal(h_win, 2, 0, 80);
  1383. X    mvwattrstr(h_win, 4, 0, A_BOLD, "       Major Functions          Utility Functions         File Functions\n\n");
  1384. X    mvwprintw(h_win,  6,  2, "Dialing Directory.%4.4s-D  Program Info ....%4.4s-I  Send Files ....%4.4s-<up>", hot, hot, hot);
  1385. X    mvwprintw(h_win,  7,  2, "Auto Redial ......%4.4s-R  Setup Screen ....%4.4s-S  Receive Files .%4.4s-<down>", hot, hot, hot);
  1386. X    mvwprintw(h_win,  8,  2, "Keyboard Macros ..%4.4s-M  Change Directory.%4.4s-B  Pass Thru Mode.%4.4s-T", hot, hot, hot);
  1387. X    mvwprintw(h_win,  9,  2, "Line Settings ....%4.4s-P  Clear Screen ....%4.4s-C  Directory .....%4.4s-F", hot, hot, hot);
  1388. X    mvwprintw(h_win, 10,  2, "Exit Pcomm .......%4.4s-X  Toggle Duplex ...%4.4s-E  Screen Dump ...%4.4s-G", hot, hot, hot);
  1389. X    mvwprintw(h_win, 11,  2, "Unix Gateway .....%4.4s-4  Hang Up Phone ...%4.4s-H  Start Data Log.%4.4s-1", hot, hot, hot);
  1390. X    mvwprintw(h_win, 12, 28, "Printer On/Off ..%4.4s-L  Toggle Log ....%4.4s-2", hot, hot);
  1391. X    mvwprintw(h_win, 13, 28, "Toggle CR-CR/LF .%4.4s-3", hot);
  1392. X    mvwprintw(h_win, 14, 28, "Break Key .......%4.4s-7", hot);
  1393. X
  1394. X    box(h_win, VERT, HORZ);
  1395. X    mvwaddstr(h_win, 16, 26, " Press any key to continue ");
  1396. X    wrefresh(h_win);
  1397. X
  1398. X    wgetch(h_win);
  1399. X    if (fd == -1) {
  1400. X        werase(h_win);
  1401. X        wrefresh(h_win);
  1402. X    }
  1403. X    delwin(h_win);
  1404. X    return;
  1405. X}
  1406. SHAR_EOF
  1407. if test 1779 -ne "`wc -c < 'help.c'`"
  1408. then
  1409.     echo shar: "error transmitting 'help.c'" '(should have been 1779 characters)'
  1410. fi
  1411. fi
  1412. echo shar: "extracting 'info.c'" '(1548 characters)'
  1413. if test -f 'info.c'
  1414. then
  1415.     echo shar: "will not over-write existing file 'info.c'"
  1416. else
  1417. sed 's/^X//' << \SHAR_EOF > 'info.c'
  1418. X/*
  1419. X * Display the initial welcome screen (to include all of the proper
  1420. X * acknowledgements).  Press any key to continue.
  1421. X */
  1422. X
  1423. X#define VERSION    "1.2.0"
  1424. X#define DATE    "4 Feb 89"
  1425. X
  1426. X#include <stdio.h>
  1427. X#include <curses.h>
  1428. X
  1429. Xvoid
  1430. Xinfo(auto_clear)
  1431. Xint auto_clear;
  1432. X{
  1433. X    extern int fd;
  1434. X    WINDOW *w_win, *newwin();
  1435. X    char buf[80];
  1436. X                    /* display the welcome screen */
  1437. X    w_win = newwin(23, 80, 0, 0);
  1438. X    mvwaddstr(w_win, 3, 18, "PPPPPP    CCCC    OOOO    MM   MM   MM   MM");
  1439. X    mvwaddstr(w_win, 4, 18, "P    P   C       O    O   M M M M   M M M M");
  1440. X    mvwaddstr(w_win, 5, 18, "PPPPPP   C       O    O   M  M  M   M  M  M");
  1441. X    mvwaddstr(w_win, 6, 18, "P        C       O    O   M     M   M     M");
  1442. X    mvwaddstr(w_win, 7, 18, "P         CCCC    OOOO    M     M   M     M");
  1443. X
  1444. X    sprintf(buf, ">>> Pcomm Version %s <<<", VERSION);
  1445. X    mvwaddstr(w_win, 10, (80-strlen(buf))/2, buf);
  1446. X    sprintf(buf, "Release date: %s", DATE);
  1447. X    mvwaddstr(w_win, 11, (80-strlen(buf))/2, buf);
  1448. X
  1449. X    mvwaddstr(w_win, 13, 8, "Pcomm is a public domain telecommunication program for Unix that");
  1450. X    mvwaddstr(w_win, 14, 8, "is designed to operate similar to the MSDOS program, ProComm.");
  1451. X    mvwaddstr(w_win, 15, 8, "ProComm (TM) is copyrighted by Datastorm Technologies, Inc.");
  1452. X    mvwaddstr(w_win, 19, 45, "Emmet P. Gray");
  1453. X    mvwaddstr(w_win, 20, 45, "...!uunet!uiucuxc!fthood!egray");
  1454. X    wmove(w_win, 22, 79);
  1455. X    wrefresh(w_win);
  1456. X                    /* delay so you can read the herald */
  1457. X    if (auto_clear)
  1458. X        wait_key(w_win, 5);
  1459. X    else
  1460. X        wgetch(w_win);
  1461. X
  1462. X    if (fd == -1) {
  1463. X        werase(w_win);
  1464. X        wrefresh(w_win);
  1465. X    }
  1466. X    delwin(w_win);
  1467. X    return;
  1468. X}
  1469. SHAR_EOF
  1470. if test 1548 -ne "`wc -c < 'info.c'`"
  1471. then
  1472.     echo shar: "error transmitting 'info.c'" '(should have been 1548 characters)'
  1473. fi
  1474. fi
  1475. echo shar: "extracting 'init.c'" '(3065 characters)'
  1476. if test -f 'init.c'
  1477. then
  1478.     echo shar: "will not over-write existing file 'init.c'"
  1479. else
  1480. sed 's/^X//' << \SHAR_EOF > 'init.c'
  1481. X/*
  1482. X * Display the welcome screen and find the Pcomm support files.  Returns a
  1483. X * pointer to a static area (or shared memory) containing the STATUS
  1484. X * structure.  All errors are fatal.
  1485. X */
  1486. X
  1487. X#define TMP_FILE    "/tmp/pcommXXXXXX"
  1488. X
  1489. X#include <stdio.h>
  1490. X#include <curses.h>
  1491. X#include "config.h"
  1492. X#include "misc.h"
  1493. X#include "status.h"
  1494. X
  1495. X#ifdef SHAREDMEM
  1496. X#include <sys/types.h>
  1497. X#include <sys/ipc.h>
  1498. X#include <sys/shm.h>
  1499. X#endif /* SHAREDMEM */
  1500. X
  1501. Xstruct STATUS *
  1502. Xinit(short_cut)
  1503. Xchar *short_cut;
  1504. X{
  1505. X    char *strcpy();
  1506. X    struct STATUS *s_ptr;
  1507. X    void info();
  1508. X#ifdef SHAREDMEM
  1509. X    int mode;
  1510. X    extern int shm_id;
  1511. X    char *shmat(), *memset();
  1512. X    void perror(), exit();
  1513. X
  1514. X    /*
  1515. X     * Since the "pcomm_input" program does not run set-user/group-id
  1516. X     * the mode must be set so the effective ID can read/write to the
  1517. X     * shared memory segment.  Kinda strange... real ID's aren't used.
  1518. X     */
  1519. X#ifdef SETUGID
  1520. X    mode = 0666;
  1521. X#else /* SETUGID */
  1522. X    mode = 0600;
  1523. X#endif /* SETUGID */
  1524. X                    /* create a shared memory segment */
  1525. X    shm_id = shmget(IPC_PRIVATE, sizeof (struct STATUS),  mode|IPC_CREAT|IPC_EXCL|IPC_NOWAIT);
  1526. X    if (shm_id < 0) {
  1527. X        endwin();
  1528. X        perror("shmget");
  1529. X        exit(1);
  1530. X    }
  1531. X    s_ptr = (struct STATUS *) shmat(shm_id, (char *) 0, 0);
  1532. X    if ((int) s_ptr == -1) {
  1533. X        endwin();
  1534. X        perror("shmat");
  1535. X        exit(1);
  1536. X    }
  1537. X#else /* SHAREDMEM */
  1538. X    char *mktemp(), tempfile[sizeof(TMP_FILE)];
  1539. X    static struct STATUS s;
  1540. X    s_ptr = &s;
  1541. X#endif /* SHAREDMEM */
  1542. X                    /* some defaults */
  1543. X    s_ptr->fd = -1;
  1544. X    s_ptr->dup_fd = -1;
  1545. X    s_ptr->add_lf = 0;
  1546. X    s_ptr->log = 0;
  1547. X    s_ptr->print = 0;
  1548. X    strcpy(s_ptr->log_path, "NOT_DEFINED");
  1549. X
  1550. X#ifdef SHAREDMEM
  1551. X    s_ptr->clr = 0;
  1552. X    s_ptr->row = 0;
  1553. X    s_ptr->col = 0;
  1554. X    memset(s_ptr->vs, '\0', MAX_ROW * MAX_COL);
  1555. X#else /* SHAREDMEM */
  1556. X    strcpy(tempfile, TMP_FILE);
  1557. X    strcpy(s_ptr->vs_path, mktemp(tempfile));
  1558. X#endif /* SHAREDMEM */
  1559. X                    /* display herald if no short-cut */
  1560. X    if (short_cut == NULL)
  1561. X        info(AUTO_CLEAR);
  1562. X
  1563. X    erase();
  1564. X    refresh();
  1565. X    return(s_ptr);
  1566. X}
  1567. X
  1568. X/*
  1569. X * Search the extra directory (supplied on the command line), then the
  1570. X * directory in the PCOMM environmental variable, then the current working
  1571. X * directory, and lastly, the default directory.
  1572. X */
  1573. X
  1574. Xchar *
  1575. Xfindfile(extra, name)
  1576. Xchar *extra, *name;
  1577. X{
  1578. X    int i;
  1579. X    char *pcomm, *getenv(), *path, pbuf[200], *getcwd(), *str_dup();
  1580. X    char temp[200];
  1581. X
  1582. X                    /* see if PCOMM variable is set */
  1583. X    pcomm = getenv("PCOMM");
  1584. X    if (pcomm == NULL || *pcomm == '\0')
  1585. X        pcomm = NULL;
  1586. X    else {
  1587. X                    /* zap the trailing separator */
  1588. X        if (pcomm[strlen(pcomm)-1] == '/')
  1589. X            pcomm[strlen(pcomm)-1] = '\0';
  1590. X    }
  1591. X
  1592. X    for (i=0; i<4; i++) {
  1593. X                    /* directory search order */
  1594. X        switch (i) {
  1595. X            case 0:        /* extra directory from command line */
  1596. X                path = extra;
  1597. X                break;
  1598. X            case 1:        /* PCOMM environmental variable */
  1599. X                path = pcomm;
  1600. X                break;
  1601. X            case 2:        /* current working directory */
  1602. X                path = getcwd(pbuf, 200);
  1603. X                break;
  1604. X            case 3:        /* Pcomm's default directory */
  1605. X                path = DEFAULT_DIR;
  1606. X                break;
  1607. X        }
  1608. X        if (path == NULL)
  1609. X            continue;
  1610. X
  1611. X        sprintf(temp, "%s/%s", path, name);
  1612. X                    /* read permission checked */
  1613. X        if (!access(temp, 4))
  1614. X            return(str_dup(temp));
  1615. X    }
  1616. X    return(NULL);
  1617. X}
  1618. SHAR_EOF
  1619. if test 3065 -ne "`wc -c < 'init.c'`"
  1620. then
  1621.     echo shar: "error transmitting 'init.c'" '(should have been 3065 characters)'
  1622. fi
  1623. fi
  1624. echo shar: "extracting 'input.c'" '(10960 characters)'
  1625. if test -f 'input.c'
  1626. then
  1627.     echo shar: "will not over-write existing file 'input.c'"
  1628. else
  1629. sed 's/^X//' << \SHAR_EOF > 'input.c'
  1630. X/*
  1631. X * The input routines.  This program runs as a child process to the
  1632. X * Pcomm program.
  1633. X */
  1634. X
  1635. X#include <stdio.h>
  1636. X#include <signal.h>
  1637. X#include <setjmp.h>
  1638. X#define MAIN
  1639. X#include "config.h"
  1640. X#include "misc.h"
  1641. X#include "status.h"
  1642. X#include "vcs.h"
  1643. X
  1644. X#ifdef SHAREDMEM
  1645. X#include <sys/types.h>
  1646. X#include <sys/ipc.h>
  1647. X#include <sys/shm.h>
  1648. X#endif /* SHAREDMEM */
  1649. X
  1650. Xjmp_buf i_jmp;
  1651. Xint vcs_param[NUM_VCS][5];        /* positional parameters */
  1652. Xint vcs_opt[NUM_VCS][10];        /* options unique to each VCS */
  1653. Xint vcs_codes[NUM_VCS][VCS_SIZE];    /* the VCS codes */
  1654. Xint vcs_leadin[NUM_VCS];        /* unique list of lead-in characters */
  1655. Xint num_leadin;                /* length of lead-in list */
  1656. Xint hold, max_row, max_col, skip_row;
  1657. XFILE *logfp, *lprfp;
  1658. Xstruct STATUS *status;
  1659. X
  1660. X#ifdef SHAREDMEM
  1661. X#define VROW    status->row
  1662. X#define VCOL    status->col
  1663. X#define VS    status->vs
  1664. X#else /* SHAREDMEM */
  1665. Xint VROW, VCOL;
  1666. Xchar VS[MAX_ROW][MAX_COL];
  1667. Xstruct STATUS s;
  1668. X#endif /* SHAREDMEM */
  1669. X
  1670. X/*
  1671. X * Read the serial port and write the characters to the screen.  Watch
  1672. X * for signals from the parent process to toggle the fancy options.
  1673. X * Writes the characters received to a virtual screen buffer.
  1674. X */
  1675. X
  1676. Xmain(argc, argv)
  1677. Xint argc;
  1678. Xchar *argv[];
  1679. X{
  1680. X    FILE *popen();
  1681. X    register int in_cnt, out_cnt;
  1682. X    int got_sig();
  1683. X    char c, *strcpy(), *bufp, in_buf[INPUT_BUF], out_buf[INPUT_BUF*2];
  1684. X    void _exit(), exit(), vcs_table(), setbuf(), vs_putchar(), vs_clear();
  1685. X#ifdef SHAREDMEM
  1686. X    int shm_id;
  1687. X    char *shmat();
  1688. X    void perror();
  1689. X#endif /* SHAREDMEM */
  1690. X                    /* set the trap for the signals */
  1691. X    signal(SIGALRM, SIG_IGN);
  1692. X    signal(SIGHUP,  SIG_IGN);
  1693. X    signal(SIGQUIT, SIG_IGN);
  1694. X    signal(SIGUSR1, got_sig);
  1695. X    signal(SIGUSR2, got_sig);
  1696. X    signal(SIGINT,  got_sig);
  1697. X    signal(SIGTERM, got_sig);
  1698. X
  1699. X    setbuf(stdout, (char *) NULL);
  1700. X                    /* for the curious... */
  1701. X    if (argc == 1) {
  1702. X        fprintf(stderr, "This is the input routine for the Pcomm program\n");
  1703. X        fprintf(stderr, "It is not designed to be run as a separate program\n");
  1704. X        exit(1);
  1705. X    }
  1706. X
  1707. X#ifdef SHAREDMEM
  1708. X    shm_id = atoi(argv[1]);
  1709. X    status = (struct STATUS *) shmat(shm_id, (char *) 0, 0);
  1710. X    if ((int) status == -1) {
  1711. X        perror("shmat");
  1712. X        _exit(1);
  1713. X    }
  1714. X#else /* SHAREDMEM */
  1715. X    status = &s;
  1716. X#endif /* SHAREDMEM */
  1717. X                    /* load the VCS table */
  1718. X    vcs_table();
  1719. X    if (max_row > MAX_ROW)
  1720. X        max_row = MAX_ROW;
  1721. X    if (max_col > MAX_COL-1)
  1722. X        max_col = MAX_COL-1;
  1723. X                    /* parse the command line */
  1724. X#ifndef SHAREDMEM
  1725. X    status->fd = atoi(argv[1]);
  1726. X    status->dup_fd = atoi(argv[2]);
  1727. X    status->add_lf = atoi(argv[3]);
  1728. X    status->log = atoi(argv[4]);
  1729. X    status->print = atoi(argv[5]);
  1730. X    strcpy(status->log_path, argv[6]);
  1731. X    strcpy(status->vs_path, argv[7]);
  1732. X#endif /* SHAREDMEM */
  1733. X
  1734. X    skip_row = 0;
  1735. X
  1736. X#ifdef SHAREDMEM
  1737. X    if (status->clr)
  1738. X        skip_row = 1;
  1739. X#else /* SHAREDMEM */
  1740. X                    /* read previous screen */
  1741. X    if (!access(status->vs_path, 0))
  1742. X        read_vs();
  1743. X    else
  1744. X        skip_row = 1;
  1745. X#endif /* SHAREDMEM */
  1746. X
  1747. X    hold = 0;
  1748. X                    /* start up file pointers */
  1749. X    lprfp = (FILE *) NULL;
  1750. X    logfp = (FILE *) NULL;
  1751. X
  1752. X    switch (setjmp(i_jmp)) {
  1753. X        case 0:            /* no signal */
  1754. X            break;
  1755. X        case 1:            /* toggle the data logging */
  1756. X            status->log = status->log ? 0 : 1;
  1757. X            break;
  1758. X        case 2:            /* toggle the printer */
  1759. X            status->print = status->print ? 0 : 1;
  1760. X            break;
  1761. X        case 3:            /* suspend the input */
  1762. X            hold = hold ? 0 : 1;
  1763. X#ifndef SHAREDMEM
  1764. X            if (hold)
  1765. X                write_vs();
  1766. X#endif /* SHAREDMEM */
  1767. X            break;
  1768. X        case 4:            /* clean up and go home */
  1769. X            if (status->log)
  1770. X                fclose(logfp);
  1771. X            if (status->print) {
  1772. X                putc('\f', lprfp);
  1773. X                pclose(lprfp);
  1774. X            }
  1775. X#ifdef SHAREDMEM
  1776. X                    /* detach shared memory */
  1777. X            shmdt((char *) status);
  1778. X#endif /* SHAREDMEM */
  1779. X            _exit(0);
  1780. X            break;
  1781. X    }
  1782. X                    /* any signal will awaken pause() */
  1783. X    if (hold)
  1784. X#ifdef BSD
  1785. X        sigpause(0);
  1786. X#else /* BSD */
  1787. X        pause();
  1788. X#endif /* BSD */
  1789. X                    /* open or close the printer */
  1790. X    if (status->print && lprfp == NULL)
  1791. X        lprfp = popen(LPR, "w");
  1792. X
  1793. X    if (!status->print && lprfp != NULL) {
  1794. X        putc('\f', lprfp);
  1795. X        pclose(lprfp);
  1796. X        lprfp = (FILE *) NULL;
  1797. X    }
  1798. X                    /* open or close the log file */
  1799. X    if (status->log && logfp == NULL) {
  1800. X        if (strcmp(status->log_path, "NOT_DEFINED")) {
  1801. X            if (!(logfp = fopen(status->log_path, "a")))
  1802. X                status->log = 0;
  1803. X        }
  1804. X        else
  1805. X            status->log = 0;
  1806. X    }
  1807. X    if (!status->log && logfp != NULL) {
  1808. X        fclose(logfp);
  1809. X        logfp = (FILE *) NULL;
  1810. X    }
  1811. X
  1812. X#ifdef SHAREDMEM
  1813. X    if (status->clr) {
  1814. X        status->clr = 0;
  1815. X        vs_clear();
  1816. X    }
  1817. X#else /* SHAREDMEM */
  1818. X                    /* clear if vs_path doesn't exist */
  1819. X    if (access(status->vs_path, 0))
  1820. X        vs_clear();
  1821. X#endif /* SHAREDMEM */
  1822. X
  1823. X    /*
  1824. X     * The very first screen we see after dialing has the "Connected to..."
  1825. X     * message at row 0, therefore we start our virtual screen at row 1.
  1826. X     */
  1827. X    if (skip_row) {
  1828. X        skip_row = 0;
  1829. X        VROW = 1;
  1830. X    }
  1831. X                    /* here we go... */
  1832. X    while (1) {
  1833. X        if ((in_cnt = read(status->fd, in_buf, INPUT_BUF)) <= 0)
  1834. X            continue;
  1835. X                    /* send a duplicate to Pcomm */
  1836. X        if (status->dup_fd != -1)
  1837. X            write(status->dup_fd, in_buf, in_cnt);
  1838. X
  1839. X                    /* "peel" the buffer one at a time */
  1840. X        out_cnt = 0;
  1841. X        bufp = in_buf;
  1842. X        while (--in_cnt >= 0) {
  1843. X            c = *bufp++ & 0xff;
  1844. X                    /* send to logfile */
  1845. X            if (status->log) {
  1846. X                if (c == '\r' && status->add_lf)
  1847. X                    putc('\n', logfp);
  1848. X                    /* no carriage returns in logfile */
  1849. X                if (c != '\r')
  1850. X                    putc(c, logfp);
  1851. X            }
  1852. X                    /* send to printer too? */
  1853. X            if (status->print)
  1854. X                putc(c, lprfp);
  1855. X
  1856. X                    /* put a char in virtual screen */
  1857. X            vs_putchar(c);
  1858. X
  1859. X                    /* build the output buffer */
  1860. X            out_buf[out_cnt++] = c;
  1861. X            if (c == '\r' && status->add_lf)
  1862. X                out_buf[out_cnt++] = '\n';
  1863. X
  1864. X                    /* output in smaller chunks */
  1865. X            if (out_cnt >= OUTPUT_BUF) {
  1866. X                fwrite(out_buf, sizeof(char), out_cnt, stdout);
  1867. X                out_cnt = 0;
  1868. X            }
  1869. X        }
  1870. X        if (out_cnt)
  1871. X            fwrite(out_buf, sizeof(char), out_cnt, stdout);
  1872. X    }
  1873. X}
  1874. X
  1875. X/*
  1876. X * Figure out which signal we just received, and fix the return code of
  1877. X * the setjmp function above to the proper value.
  1878. X */
  1879. X
  1880. Xint
  1881. Xgot_sig(sig)
  1882. Xint sig;
  1883. X{
  1884. X    switch (sig) {
  1885. X        case SIGUSR1:
  1886. X            signal(SIGUSR1, got_sig);
  1887. X            longjmp(i_jmp, 1);
  1888. X        case SIGUSR2:
  1889. X            signal(SIGUSR2, got_sig);
  1890. X            longjmp(i_jmp, 2);
  1891. X        case SIGINT:
  1892. X            signal(SIGINT, got_sig);
  1893. X            longjmp(i_jmp, 3);
  1894. X        case SIGTERM:
  1895. X            signal(SIGTERM, got_sig);
  1896. X            longjmp(i_jmp, 4);
  1897. X    }
  1898. X}
  1899. X
  1900. X/*
  1901. X * Put a character in the virtual screen.  This routine saves incoming
  1902. X * characters in a two dimensional buffer designed to mimic the real
  1903. X * screen.
  1904. X */
  1905. X
  1906. Xvoid
  1907. Xvs_putchar(c)
  1908. Xchar c;
  1909. X{
  1910. X    register int i;
  1911. X    char *memset();
  1912. X    int tab_stop;
  1913. X    void vs_scroll();
  1914. X
  1915. X    switch (vcs_filter(c)) {
  1916. X        case MAYBE:        /* wait and see... */
  1917. X            break;
  1918. X        case 256+HOME:        /* home virtual screen "cursor" */
  1919. X            VROW = 0;
  1920. X            VCOL = 0;
  1921. X            break;
  1922. X        case 256+CLR_EOL:    /* clear to end of line */
  1923. X            memset(&VS[VROW][VCOL], ' ', max_col - VCOL);
  1924. X            VCOL = max_col -1;
  1925. X            break;
  1926. X        case 256+CLR_EOS:    /* clear to end of screen */
  1927. X            memset(&VS[VROW][VCOL], ' ', max_col - VCOL);
  1928. X            for (i=VROW+1; i<max_row; i++)
  1929. X                memset(VS[i], ' ', max_col);
  1930. X            VROW = max_row -1;
  1931. X            VCOL = max_col -1;
  1932. X            break;
  1933. X        case 256+CLEAR:        /* clear all and home "cursor" */
  1934. X            for (i=0; i<max_row; i++)
  1935. X                memset(VS[i], ' ', max_col);
  1936. X            VROW = 0;
  1937. X            VCOL = 0;
  1938. X            break;
  1939. X        case 256+MV_UP:        /* move "cursor" up */
  1940. X            VROW--;
  1941. X            if (VROW < 0)
  1942. X                VROW = 0;
  1943. X            break;
  1944. X        case 256+MV_DOWN:    /* move "cursor" down */
  1945. X            VROW++;
  1946. X            if (VROW >= max_row)
  1947. X                VROW = max_row -1;
  1948. X            break;
  1949. X        case 256+MV_RIGHT:    /* move "cursor" right */
  1950. X            VCOL++;
  1951. X            if (VCOL >= max_col)
  1952. X                VCOL = max_col -1;
  1953. X            break;
  1954. X        case 256+MV_LEFT:    /* move "cursor" left */
  1955. X        case BS:        /* non destructive back space */
  1956. X            VCOL--;
  1957. X            if (VCOL < 0)
  1958. X                VCOL = 0;
  1959. X            break;
  1960. X        case 256+MV_DIRECT:    /* direct cursor movement */
  1961. X            VROW = vcs_param[MV_DIRECT][0];
  1962. X            VCOL = vcs_param[MV_DIRECT][1];
  1963. X
  1964. X                    /* if "add one" and "decimal" */
  1965. X            if (vcs_opt[MV_DIRECT][0] && vcs_opt[MV_DIRECT][1]) {
  1966. X                VROW--;
  1967. X                VCOL--;
  1968. X            }
  1969. X                    /* if "character" */
  1970. X            if (vcs_opt[MV_DIRECT][2]) {
  1971. X                    /* if "add offset" */
  1972. X                if (vcs_opt[MV_DIRECT][3]) {
  1973. X                    VROW -= vcs_opt[MV_DIRECT][5];
  1974. X                    VCOL -= vcs_opt[MV_DIRECT][5];
  1975. X                }
  1976. X                    /* if "subtract offset" */
  1977. X                if (vcs_opt[MV_DIRECT][4]) {
  1978. X                    VROW += vcs_opt[MV_DIRECT][5];
  1979. X                    VCOL += vcs_opt[MV_DIRECT][5];
  1980. X                }
  1981. X                VROW--;
  1982. X                VCOL--;
  1983. X            }
  1984. X            break;
  1985. X        case 0:
  1986. X        case 7:            /* skip NULL and "bell" character */
  1987. X            break;
  1988. X        case '\t':        /* tab character */
  1989. X            tab_stop = VCOL + 8 - (VCOL % 8);
  1990. X                    /* if wrap around */
  1991. X            if (tab_stop >= max_col) {
  1992. X                    /* spaces up to eol */
  1993. X                memset(&VS[VROW][VCOL], ' ', max_col - VCOL);
  1994. X                VROW++;
  1995. X                if (VROW >= max_row)
  1996. X                    vs_scroll();
  1997. X
  1998. X                    /* the remainder of the tab */
  1999. X                VCOL = tab_stop - max_col;
  2000. X            }
  2001. X            else {
  2002. X                memset(&VS[VROW][VCOL], ' ', tab_stop - VCOL);
  2003. X                VCOL = tab_stop;
  2004. X            }
  2005. X            break;
  2006. X        case '\r':        /* carriage return */
  2007. X            VCOL = 0;
  2008. X            if (!status->add_lf)
  2009. X                break;
  2010. X            /* fall thru...*/
  2011. X        case '\n':        /* line feed */
  2012. X            VROW++;
  2013. X            if (VROW >= max_row)
  2014. X                vs_scroll();
  2015. X            break;
  2016. X        default:        /* a normal character */
  2017. X            VS[VROW][VCOL] = c;
  2018. X            VCOL++;
  2019. X                    /* wrap around */
  2020. X            if (VCOL >= max_col) {
  2021. X                VCOL = 0;
  2022. X                VROW++;
  2023. X                if (VROW >= max_row)
  2024. X                    vs_scroll();
  2025. X            }
  2026. X            break;
  2027. X    }
  2028. X    return;
  2029. X}
  2030. X
  2031. X#ifndef SHAREDMEM
  2032. X/*
  2033. X * Save the virtual screen to a file.
  2034. X */
  2035. X
  2036. Xint
  2037. Xwrite_vs()
  2038. X{
  2039. X    FILE *fp;
  2040. X    register int i;
  2041. X
  2042. X    if (!(fp = fopen(status->vs_path, "w")))
  2043. X        return(1);
  2044. X                    /* current x y coordinates */
  2045. X    fprintf(fp, "%d,%d\n", VROW, VCOL);
  2046. X
  2047. X    for (i=0; i<max_row; i++) {
  2048. X        VS[i][max_col] = '\0';
  2049. X        fprintf(fp, "%s\n", VS[i]);
  2050. X    }
  2051. X    fclose(fp);
  2052. X    return(0);
  2053. X}
  2054. X
  2055. X/*
  2056. X * Get the virtual screen image from the file.  Since input() gets
  2057. X * killed from time to time, the vs_path file is the only way to retain
  2058. X * the screen image.
  2059. X */
  2060. X
  2061. Xint
  2062. Xread_vs()
  2063. X{
  2064. X    FILE *fp;
  2065. X    register int i;
  2066. X    char buf[10];
  2067. X                    /* in case the fopen fails... */
  2068. X    VROW = 0;
  2069. X    VCOL = 0;
  2070. X                    /* not guaranteed to exist yet */
  2071. X    if (!(fp = fopen(status->vs_path, "r")))
  2072. X        return(1);
  2073. X                    /* get the x, y coordinates */
  2074. X    fgets(buf, 10, fp);
  2075. X    sscanf(buf, "%d,%d\n", &VROW, &VCOL);
  2076. X
  2077. X                    /* read the file into the vs array */
  2078. X    for (i=0; i<max_row; i++) {
  2079. X        fgets(VS[i], MAX_COL, fp);
  2080. X        VS[i][max_col] = '\0';
  2081. X    }
  2082. X    fclose(fp);
  2083. X    return(0);
  2084. X}
  2085. X#endif /* SHAREDMEM */
  2086. X
  2087. X/*
  2088. X * If the user clears the screen with the ^A-C command, the input
  2089. X * has to be in sync.
  2090. X */
  2091. X
  2092. Xvoid
  2093. Xvs_clear()
  2094. X{
  2095. X    register int i;
  2096. X    char *memset();
  2097. X
  2098. X    for (i=0; i<max_row; i++)
  2099. X        memset(VS[i], ' ', max_col);
  2100. X                    /* home the "cursor" */
  2101. X    VROW = 0;
  2102. X    VCOL = 0;
  2103. X    return;
  2104. X}
  2105. X
  2106. X/*
  2107. X * Do a software scroll on the virtual screen.  Does not alter the
  2108. X * "col" variable.
  2109. X */
  2110. X
  2111. Xvoid
  2112. Xvs_scroll()
  2113. X{
  2114. X    char *strcpy(), *memset();
  2115. X                    /* move 'em up 1 line */
  2116. X#ifdef MEMMOVE
  2117. X    char *MEMMOVE();
  2118. X
  2119. X    MEMMOVE(VS[0], VS[1], (max_row -1) * MAX_COL);
  2120. X#else /* MEMMOVE */
  2121. X    register int i;
  2122. X
  2123. X    for (i=0; i<max_row-1; i++)
  2124. X        strcpy(VS[i], VS[i+1]);
  2125. X#endif /* MEMMOVE */
  2126. X                    /* clear the bottom line */
  2127. X    memset(VS[max_row-1], ' ', max_col);
  2128. X
  2129. X    VROW = max_row -1;
  2130. X    return;
  2131. X}
  2132. X
  2133. X#ifdef BSD
  2134. X/*
  2135. X * Copies the character c, n times to string str
  2136. X */
  2137. X
  2138. Xchar *
  2139. Xmemset(str, c, n)
  2140. Xchar *str, c;
  2141. Xint n;
  2142. X{
  2143. X    char *s1 = str;
  2144. X
  2145. X    while (n > 0) {
  2146. X        --n;
  2147. X        *s1++ = c;
  2148. X    }
  2149. X    return(str);
  2150. X}
  2151. X#endif /* BSD */
  2152. SHAR_EOF
  2153. if test 10960 -ne "`wc -c < 'input.c'`"
  2154. then
  2155.     echo shar: "error transmitting 'input.c'" '(should have been 10960 characters)'
  2156. fi
  2157. fi
  2158. echo shar: "extracting 'list_dir.c'" '(1635 characters)'
  2159. if test -f 'list_dir.c'
  2160. then
  2161.     echo shar: "will not over-write existing file 'list_dir.c'"
  2162. else
  2163. sed 's/^X//' << \SHAR_EOF > 'list_dir.c'
  2164. X/*
  2165. X * Do a shell escape with the "ls" command.  Additional command line options
  2166. X * are allowed at run time.
  2167. X */
  2168. X
  2169. X#define LS_CMD "ls -aC"
  2170. X
  2171. X#include <stdio.h>
  2172. X#include <curses.h>
  2173. X#include "config.h"
  2174. X#include "misc.h"
  2175. X
  2176. Xvoid
  2177. Xlist_dir()
  2178. X{
  2179. X    extern int fd;
  2180. X    WINDOW *ls_win, *newwin();
  2181. X    FILE *pfp, *n_popen();
  2182. X    int lines, oops;
  2183. X    char *ans, *cwd, *getcwd(), buf[200], *get_str();
  2184. X
  2185. X    ls_win = newwin(6, 70, 8, 5);
  2186. X
  2187. X    cwd = getcwd(buf, 200);
  2188. X
  2189. X    mvwprintw(ls_win, 2, 4, "Current directory: %s", cwd);
  2190. X    mvwaddstr(ls_win, 3, 4, "File spec (wildcards allowed): ");
  2191. X    box(ls_win, VERT, HORZ);
  2192. X
  2193. X    mvwattrstr(ls_win, 0, 3, A_BOLD, " List Directory ");
  2194. X    wmove(ls_win, 3, 35);
  2195. X    wrefresh(ls_win);
  2196. X
  2197. X    if ((ans = get_str(ls_win, 80, "", "\n")) == NULL) {
  2198. X        if (fd == -1) {
  2199. X            werase(ls_win);
  2200. X            wrefresh(ls_win);
  2201. X        }
  2202. X        delwin(ls_win);
  2203. X        return;
  2204. X    }
  2205. X                    /* popen() an ls */
  2206. X    sprintf(buf, "%s %s", LS_CMD, ans);
  2207. X    pfp = n_popen(buf, "r");
  2208. X                    /* make a bigger window */
  2209. X    werase(ls_win);
  2210. X    wrefresh(ls_win);
  2211. X    delwin(ls_win);
  2212. X    ls_win = newwin(LINES-1, COLS, 0, 0);
  2213. X    touchwin(ls_win);
  2214. X                    /* a crude kind of paging */
  2215. X    oops = 0;
  2216. X    lines = 0;
  2217. X    while (fgets(buf, BUFSIZ, pfp) != NULL) {
  2218. X        waddstr(ls_win, buf);
  2219. X        lines++;
  2220. X        if (lines == LINES-2) {
  2221. X            lines = 0;
  2222. X            mvwaddstr(ls_win, LINES-2, 28, "Press any key for more");
  2223. X            wrefresh(ls_win);
  2224. X            if (wgetch(ls_win) == ESC) {
  2225. X                oops++;
  2226. X                break;
  2227. X            }
  2228. X            werase(ls_win);
  2229. X            wrefresh(ls_win);
  2230. X        }
  2231. X    }
  2232. X    n_pclose(pfp);
  2233. X
  2234. X    if (!oops) {
  2235. X        mvwaddstr(ls_win, LINES-2, 25, "Press any key to continue");
  2236. X        wrefresh(ls_win);
  2237. X        wgetch(ls_win);
  2238. X    }
  2239. X    if (fd == -1) {
  2240. X        werase(ls_win);
  2241. X        wrefresh(ls_win);
  2242. X    }
  2243. X    delwin(ls_win);
  2244. X    return;
  2245. X}
  2246. SHAR_EOF
  2247. if test 1635 -ne "`wc -c < 'list_dir.c'`"
  2248. then
  2249.     echo shar: "error transmitting 'list_dir.c'" '(should have been 1635 characters)'
  2250. fi
  2251. fi
  2252. echo shar: "extracting 'ls_menu.c'" '(4816 characters)'
  2253. if test -f 'ls_menu.c'
  2254. then
  2255.     echo shar: "will not over-write existing file 'ls_menu.c'"
  2256. else
  2257. sed 's/^X//' << \SHAR_EOF > 'ls_menu.c'
  2258. X/*
  2259. X * Routines for displaying current line settings and prompting for changes.
  2260. X */
  2261. X
  2262. X#include <stdio.h>
  2263. X#include <curses.h>
  2264. X#include "config.h"
  2265. X#include "dial_dir.h"
  2266. X#include "misc.h"
  2267. X#include "param.h"
  2268. X
  2269. X/*
  2270. X * Display the current line settings and prompt for changes.  A non-zero
  2271. X * return code means settings were changed.
  2272. X */
  2273. X
  2274. Xint
  2275. Xls_menu()
  2276. X{
  2277. X    extern int fd;
  2278. X    WINDOW *l_win, *newwin();
  2279. X    int num, ret_code;
  2280. X    void disp_settings();
  2281. X
  2282. X    l_win = newwin(20, 47, 0, 16);
  2283. X
  2284. X    mvwattrstr(l_win, 1, 16, A_BOLD, "Line Settings");
  2285. X    horizontal(l_win, 2, 0, 47);
  2286. X    mvwaddstr(l_win, 6, 5, "1)     300,E,7,1     7)     300,N,8,1");
  2287. X    mvwaddstr(l_win, 7, 5, "2)    1200,E,7,1     8)    1200,N,8,1");
  2288. X    mvwaddstr(l_win, 8, 5, "3)    2400,E,7,1     9)    2400,N,8,1");
  2289. X    mvwaddstr(l_win, 9, 5, "4)    4800,E,7,1    10)    4800,N,8,1");
  2290. X    mvwaddstr(l_win, 10, 5, "5)    9600,E,7,1    11)    9600,N,8,1");
  2291. X    mvwaddstr(l_win, 11, 5, "6)   19200,E,7,1    12)   19200,N,8,1");
  2292. X    mvwaddstr(l_win, 13, 4, "Parity        Data Bits       Stop Bits");
  2293. X    mvwaddstr(l_win, 14, 4, "13) Odd       14) 7 bits      16) 1 bit");
  2294. X    mvwaddstr(l_win, 15, 18, "15) 8 bits      17) 2 bits");
  2295. X    mvwaddstr(l_win, 17, 4, "18) Save Changes");
  2296. X    mvwattrstr(l_win, 17, 28, A_BOLD, "YOUR CHOICE:");
  2297. X    wmove(l_win, 17, 41);
  2298. X    box(l_win, VERT, HORZ);
  2299. X
  2300. X    mvwaddstr(l_win, 19, 13, " Press <ESC> to return ");
  2301. X                    /* display current settings */
  2302. X    disp_settings(l_win);
  2303. X    wmove(l_win, 17, 41);
  2304. X    wrefresh(l_win);
  2305. X                    /* get the options */
  2306. X    ret_code = 0;
  2307. X    while ((num = get_num(l_win, 2)) != -1) {
  2308. X        switch (num) {
  2309. X            case 1:
  2310. X                dir->baud[dir->d_cur] = 300;
  2311. X                dir->parity[dir->d_cur] = 'E';
  2312. X                dir->dbits[dir->d_cur] = 7;
  2313. X                dir->sbits[dir->d_cur] = 1;
  2314. X                break;
  2315. X            case 2:
  2316. X                dir->baud[dir->d_cur] = 1200;
  2317. X                dir->parity[dir->d_cur] = 'E';
  2318. X                dir->dbits[dir->d_cur] = 7;
  2319. X                dir->sbits[dir->d_cur] = 1;
  2320. X                break;
  2321. X            case 3:
  2322. X                dir->baud[dir->d_cur] = 2400;
  2323. X                dir->parity[dir->d_cur] = 'E';
  2324. X                dir->dbits[dir->d_cur] = 7;
  2325. X                dir->sbits[dir->d_cur] = 1;
  2326. X                break;
  2327. X            case 4:
  2328. X                dir->baud[dir->d_cur] = 4800;
  2329. X                dir->parity[dir->d_cur] = 'E';
  2330. X                dir->dbits[dir->d_cur] = 7;
  2331. X                dir->sbits[dir->d_cur] = 1;
  2332. X                break;
  2333. X            case 5:
  2334. X                dir->baud[dir->d_cur] = 9600;
  2335. X                dir->parity[dir->d_cur] = 'E';
  2336. X                dir->dbits[dir->d_cur] = 7;
  2337. X                dir->sbits[dir->d_cur] = 1;
  2338. X                break;
  2339. X            case 6:
  2340. X                dir->baud[dir->d_cur] = 19200;
  2341. X                dir->parity[dir->d_cur] = 'E';
  2342. X                dir->dbits[dir->d_cur] = 7;
  2343. X                dir->sbits[dir->d_cur] = 1;
  2344. X                break;
  2345. X            case 7:
  2346. X                dir->baud[dir->d_cur] = 300;
  2347. X                dir->parity[dir->d_cur] = 'N';
  2348. X                dir->dbits[dir->d_cur] = 8;
  2349. X                dir->sbits[dir->d_cur] = 1;
  2350. X                break;
  2351. X            case 8:
  2352. X                dir->baud[dir->d_cur] = 1200;
  2353. X                dir->parity[dir->d_cur] = 'N';
  2354. X                dir->dbits[dir->d_cur] = 8;
  2355. X                dir->sbits[dir->d_cur] = 1;
  2356. X                break;
  2357. X            case 9:
  2358. X                dir->baud[dir->d_cur] = 2400;
  2359. X                dir->parity[dir->d_cur] = 'N';
  2360. X                dir->dbits[dir->d_cur] = 8;
  2361. X                dir->sbits[dir->d_cur] = 1;
  2362. X                break;
  2363. X            case 10:
  2364. X                dir->baud[dir->d_cur] = 4800;
  2365. X                dir->parity[dir->d_cur] = 'N';
  2366. X                dir->dbits[dir->d_cur] = 8;
  2367. X                dir->sbits[dir->d_cur] = 1;
  2368. X                break;
  2369. X            case 11:
  2370. X                dir->baud[dir->d_cur] = 9600;
  2371. X                dir->parity[dir->d_cur] = 'N';
  2372. X                dir->dbits[dir->d_cur] = 8;
  2373. X                dir->sbits[dir->d_cur] = 1;
  2374. X                break;
  2375. X            case 12:
  2376. X                dir->baud[dir->d_cur] = 19200;
  2377. X                dir->parity[dir->d_cur] = 'N';
  2378. X                dir->dbits[dir->d_cur] = 8;
  2379. X                dir->sbits[dir->d_cur] = 1;
  2380. X                break;
  2381. X            case 13:
  2382. X                dir->parity[dir->d_cur] = 'O';
  2383. X                break;
  2384. X            case 14:
  2385. X                dir->dbits[dir->d_cur] = 7;
  2386. X                break;
  2387. X            case 15:
  2388. X                dir->dbits[dir->d_cur] = 8;
  2389. X                break;
  2390. X            case 16:
  2391. X                dir->sbits[dir->d_cur] = 1;
  2392. X                break;
  2393. X            case 17:
  2394. X                dir->sbits[dir->d_cur] = 2;
  2395. X                break;
  2396. X            case 18:
  2397. X                    /* copy the current settings */
  2398. X                param->d_baud = dir->baud[dir->d_cur];
  2399. X                param->d_parity = dir->parity[dir->d_cur];
  2400. X                param->d_dbits = dir->dbits[dir->d_cur];
  2401. X                param->d_sbits = dir->sbits[dir->d_cur];
  2402. X                /*
  2403. X                 * We've changed the values in memory even
  2404. X                 * if the update fails.
  2405. X                 */
  2406. X                if (up_param()) {
  2407. X                    touchwin(l_win);
  2408. X                    wrefresh(l_win);
  2409. X                }
  2410. X                break;
  2411. X            default:
  2412. X                beep();
  2413. X        }
  2414. X        ret_code++;
  2415. X        disp_settings(l_win);
  2416. X        mvwaddstr(l_win, 17, 41, "    ");
  2417. X        wmove(l_win, 17, 41);
  2418. X        wrefresh(l_win);
  2419. X    }
  2420. X    if (fd == -1) {
  2421. X        werase(l_win);
  2422. X        wrefresh(l_win);
  2423. X    }
  2424. X    delwin(l_win);
  2425. X    return(ret_code);
  2426. X}
  2427. X
  2428. X/*
  2429. X * Display the current settings.  Formats the entire string at one
  2430. X * time, in case you've got a magic cookie terminal.
  2431. X */
  2432. X
  2433. Xstatic void
  2434. Xdisp_settings(win)
  2435. XWINDOW *win;
  2436. X{
  2437. X    extern int xmc;
  2438. X    char buf[40];
  2439. X
  2440. X    sprintf(buf, "Current Settings: %5d,%c,%d,%d", dir->baud[dir->d_cur],
  2441. X     dir->parity[dir->d_cur], dir->dbits[dir->d_cur],
  2442. X     dir->sbits[dir->d_cur]);
  2443. X
  2444. X    if (xmc > 0) {
  2445. X        touchwin(win);
  2446. X        clear_line(win, 4, 8, TRUE);
  2447. X        wrefresh(win);
  2448. X    }
  2449. X    mvwattrstr(win, 4, 8, A_BOLD, buf);
  2450. X    return;
  2451. X}
  2452. SHAR_EOF
  2453. if test 4816 -ne "`wc -c < 'ls_menu.c'`"
  2454. then
  2455.     echo shar: "error transmitting 'ls_menu.c'" '(should have been 4816 characters)'
  2456. fi
  2457. fi
  2458. exit 0
  2459. #    End of shell archive
  2460.  
  2461.  
  2462.